Videos: Streamlines, Pathlines, Streaklines

Ingo Steldermann

Chair of Methods for Model-Based Development in Computational Engineering

2024-04-18

Videos

The handwritten notes of the following videos are uploaded in the Slides section.

lecture video on Moodle

exercise video on Moodle

Velocity field

\[ \begin{pmatrix} u \\ v \end{pmatrix} = \begin{pmatrix} \alpha \, t \, x - y \\ \alpha \, t \, y + x \end{pmatrix} \]

#| standalone: true
#| viewerHeight: 480

from shiny import App, render, ui
import numpy as np
import matplotlib.pyplot as plt

app_ui = ui.page_fluid(
    ui.layout_sidebar(
        ui.panel_sidebar(
            ui.input_slider("time", "Start Time & time for streamlines", 0, 10, 0, step=0.5),
            ui.input_slider("time_end", "End Time", 1, 10, 1, step=0.1),
            ui.input_slider("dt", "Integration resolution (dt)", 0.001, 0.1, 0.001, step=0.001),
            ui.input_slider("alpha", "alpha", 0., 2, 1, step=0.01),
            ui.input_numeric("x0", "x0", 0.3, min=-2, max=2, step=0.1),
            ui.input_numeric("y0", "y0", 0.3, min=-2, max=2, step=0.1),
        ),
        ui.panel_main(
            ui.output_plot("plot"),
        ),
    ),
)


def get_u(t, x, y, alpha):
  return alpha *t * x - y

def get_v(t, x, y, alpha):
  return alpha *t * y + x

def pathline(x0, y0, t0, tend, dt, alpha):
  N = int((tend-t0)/dt)+1
  X = [x0]
  Y = [y0]
  for i in range(N):
    t = i * dt + t0
    x = X[-1]
    y = Y[-1]
    X.append(x+ dt * get_u(t, x, y, alpha))
    Y.append(y+ dt * get_v(t, x, y, alpha))
  return X, Y

def streamline(x0, y0, t0, dt, alpha):
  X = [x0]
  Y = [y0]
  N = int(20/dt)
  for i in range(N):
    t = i * dt + t0
    x = X[-1]
    y = Y[-1]
    X.append(x+ dt * get_u(t0, x, y, alpha))
    Y.append(y+ dt * get_v(t0, x, y, alpha))
  return X, Y

def streakline(x0, y0, t0, tend, dt, alpha):
  _dt = np.max((dt, 0.01))
  N = int((tend-t0)/_dt)+1
  X = []
  Y = []
  for i in range(N):
    _t0 = i * _dt + t0
    _x0 = x0
    _y0 = y0
    N2 = int((tend-_t0)/_dt)+1
    for j in range(N2):
      t = j * _dt + _t0
      _x0  = _x0 + _dt * get_u(t, _x0, _y0, alpha)
      _y0  = _y0 + _dt * get_v(t, _x0, _y0, alpha)
    X.append(_x0)
    Y.append(_y0)
  return X, Y


def server(input, output, session):
    @output
    @render.plot(alt="Velocity field")
    def plot():
        dt = input.dt()
        x = np.linspace(-2, 2, 20)
        y = np.linspace(-2, 2, 20)
        xv, yv = np.meshgrid(x, y)
        alpha = input.alpha()
        u = get_u(input.time(), xv, yv, alpha)
        v = get_v(input.time(), xv, yv, alpha)
        # v = input.time() * yv + xv

        x0 = input.x0()
        y0 = input.y0()
        time_end = input.time_end()
        X_pathline, Y_pathline = pathline(x0, y0, input.time(), time_end, dt, alpha)
        X_streamline, Y_streamline = streamline(x0, y0, input.time(), dt, alpha)
        X_streakline, Y_streakline = streakline(x0, y0, input.time(), time_end, dt, alpha)
        fig, ax = plt.subplots()
        ax.set_ylim([-2, 2])
        ax.set_xlim([-2, 2])
        ax.quiver(xv, yv, u, v)
        ax.plot(X_pathline, Y_pathline, label='pathline')
        ax.plot(X_streamline, Y_streamline, label='streamline')
        ax.plot(X_streakline, Y_streakline, label='streakline')
        ax.grid()
        ax.legend()

app = App(app_ui, server)